import { miniAppPlatform } from './emun.js'
import { isTimeout } from './cache.js'
import store from '@/store'

import qs from 'qs'
export const uuid = (len, radix) => {
  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  var uuid = []
  var i
  radix = radix || chars.length
  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
  } else {
    // rfc4122, version 4 form
    var r

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'

    // Fill in random data. At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}

/**
 * 获取相对当前时间偏移offsetYear年的日期
 * @param offsetYear 向前或者向后offsetYear年，若不为数字类型则返回当前日期
 * @returns {string}
 */
export function getDate(offsetYear, format) {
  const date = new Date()
  let year = date.getFullYear()
  let month = date.getMonth() + 1
  let day = date.getDate()
  if (typeof offsetYear === 'number') {
    year = year + offsetYear
  }
  month = month > 9 ? month : '0' + month
  day = day > 9 ? day : '0' + day

  return format === 'YYYY-MM' ? `${year}-${month}` : `${year}-${month}-${day}`
}

/**
 *
 * @param form 表单对象 {a: 1, b: 2}
 * @param expect 期望校验的必填项 ['a', 'b']
 * @returns {boolean}
 */
export function isNotComplete(form, expect) {
  let flag = false
  for (const item of expect) {
    // 解决为0判断失误问题
    if (form[item] === undefined || form[item] === null || form[item] === '') {
      flag = true
      return flag
    }
  }
  return flag
}

export function handlerServiceDays(serviceExpireDate) {
  const now = new Date().getTime()
  const diff = Number(serviceExpireDate) - now
  //最小单位为1小时
  const minUnit = 1 * 60 * 60 * 1000
  const dayUnit = 24 * 60 * 60 * 1000
  //不足一小时 按一小时算
  if (diff <= minUnit) {
    return `1小时`
  }
  //大于一天 单位为天
  if (diff >= dayUnit) {
    const days = Math.ceil(diff / dayUnit)
    return `${days > 9999 ? '9999+' : days}天`
  }
  //24小时内 单位为小时
  return `${Math.ceil(diff / minUnit)}小时`
}

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'undefined' || time === null || time === 'null') {
    return ''
  } else if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

/**
 * 移动终端判断
 */

export const platformVersions = () => {
  const platform = process.env.VUE_APP_PLATFORM || uni.getSystemInfoSync().platform

  /**微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序*/
  const isMp = platform == miniAppPlatform.Mp
  /**App*/
  const isAppPlus = platform == miniAppPlatform.AppPlus
  /**App nvue*/
  const isAppPlusNvue = platform == miniAppPlatform.AppPlusNvue
  /**H5*/
  const isH5 = platform == miniAppPlatform.H5
  /**微信小程序*/
  const isMpWeixin = platform == miniAppPlatform.MpWeixin
  /**支付宝小程序*/
  const isMpAlipay = platform == miniAppPlatform.MpAlipay
  /**百度小程序*/
  const isMpBaidu = platform == miniAppPlatform.MpBaidu
  /**字节跳动小程序*/
  const isMpToutiao = platform == miniAppPlatform.MpToutiao
  /**QQ小程序*/
  const isMpQq = platform == miniAppPlatform.MpQq
  /**360小程序*/
  const isMp360 = platform == miniAppPlatform.Mp360
  /**快应用通用(包含联盟、华为)*/
  const isQuickappWebview = platform == miniAppPlatform.QuickappWebview
  /**快应用联盟*/
  const isQuickappWebviewUnion = platform == miniAppPlatform.QuickappWebviewUnion
  /**快应用华为*/
  const isQuickappWebviewHuawei = platform == miniAppPlatform.QuickappWebviewHuawei
  /**抖音小程序*/
  const isMpDouyinApp = platform == 'Douyin'
  /**头条小程序*/
  const isMpToutiaoApp = platform == 'Toutiao'
  return {
    isAppPlus,
    isAppPlusNvue,
    isH5,
    isMpWeixin,
    isMpAlipay,
    isMpBaidu,
    isMpToutiao,
    isMpQq,
    isMp,
    isMp360,
    isQuickappWebview,
    isQuickappWebviewUnion,
    isQuickappWebviewHuawei,
    isMpDouyinApp,
    isMpToutiaoApp
  }
}

/**
 *
 * @returns 获取当前移动终端
 */
export const getCurrentPlatform = () => {
  const platform = process.env.VUE_APP_PLATFORM || uni.getSystemInfoSync().platform || ''
  return platform.replace(/-/g, '')
}

// 判断已登录且未失效
export const isLogin = () => {
  const token = uni.getStorageSync('token') || ''
  const flag = !!token && !isTimeout('token')
  return flag
}

export const gotoLogin = (targetUrl = '', isReplace = false) => {
  const params = {
    targetUrl
  }
  const loginUrl = `/login/index?${qs.stringify(params)}`
  if (isReplace) {
    uni.redirectTo({
      url: loginUrl
    })
  } else {
    uni.navigateTo({
      url: loginUrl
    })
  }
}

/**
 * 邮箱检验
 */
const checkEmail = (val) => {
  let pat = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/,
    isValid = pat.test(val)
  return isValid
}

/**
 * 发票校验--单位 纳税人识别号
 */
const isTaxpayerNo = (val) => {
  const amount = /^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/
  let rt = false
  if (amount.test(val)) {
    rt = true
  }
  return rt
}

export const formatCartData = (options, type = '') => {
  console.log(options, 'options')
  let list = []
  // if (type) return options.length ? options[0].productGroups[0].productList.map((p) => ({ ...p, show: false })) : [];
  list = options
    ? options.map((c) => {
        const subList = []
        c.productGroups.map((item) => {
          item.productList.forEach((p) => {
            subList.push({ ...p, show: false })
          })
        })
        const tempObj = {
          ...c,
          productList: [...subList]
        }
        console.log(tempObj, 'tempObj')
        return tempObj
      })
    : []
  return list
}

/**
 * 获取支付宝的userId
 */
export function getAliUserId(successFn, failFn) {
  const userId = uni.getStorageSync('alipayUserId')
  console.log('alipayUserId>>>>' + userId)
  if (userId == null || userId == undefined || userId == '') {
    my.getAuthCode({
      scopes: 'auth_base',
      success: (auth) => {
        console.log('auth》》》》' + auth.authCode)
        const odyUserId = uni.getStorageSync('odyUserId') || ''
        uni.$u.http
          .getAliUserId({ authCode: auth.authCode, userId: odyUserId })
          .then((e) => {
            console.log('userId》》》》' + e && e.data)
            const tokenExpiresUtTime = 7 * 24 * 60 * 60
            uni.setStorageSync('alipayUserId', e && e.data, tokenExpiresUtTime)
            successFn && successFn()
          })
          .catch(() => {
            uni.showToast({
              icon: 'none',
              title: '网络连接失败 请稍后再试'
            })
          })
      },
      fail: () => {
        console.log('auth》》》》获取失败')
        failFn && failFn()
      }
    })
  }
}

export function isLoginJump(url, isLoginTarget) {
  if (isLogin()) {
    uni.navigateTo({
      url: url
    })
  } else {
    let targetUrl = isLoginTarget ? url : ''
    uni.reLaunch({
      url: '/login/index?targetUrl=' + targetUrl
    })
  }
}

export function toWebViewPage(model) {
  let ut = uni.getStorageSync('ut') || ''
  let linkUrl = model.linkUrl
  if (linkUrl.indexOf('?') > -1) {
    linkUrl = encodeURIComponent(model.linkUrl + '&ut=' + ut + '&formType=MINI')
  } else {
    linkUrl = encodeURIComponent(model.linkUrl + '?ut=' + ut + '&formType=MINI')
  }
  uni.navigateTo({
    url: 'pageA/webView/webView?linkUrl=' + linkUrl
  })
}

// 处方订阅 问诊咨询消息
export function sendMsg() {
  // 处方生产 问诊
  let tmplIds = []
  let flag = process.uniEnv.env === 'prod'
  console.log('process', flag, process.uniEnv.env)
  if (flag) {
    tmplIds = ['8iFTajiUxWvdkzXN0KO8drBDFuQXu2V7GR9AxzvCRI8', 'c11-YULUHJeXzMI_HrFs3vvGCCnhIjZo5OjkTh8uU2Q']
  } else {
    tmplIds = ['BVufQOQTgAOJzjKxJNh08m6Kn0EtopK5gmWYouHNvOs', 'DlmRsixxL6QHL6AQy6135mBGmCQkgSiSC2oEuaUIOmo']
  }

  return new Promise((resolve) => {
    wx.requestSubscribeMessage({
      tmplIds: tmplIds,
      success: () => {
        resolve(true)
      },
      fail: () => {
        resolve(false)
      },
      complete: (res) => {
        console.log('res', res)
      }
    })
  })
}

// 防抖
export function _debounce(fn, delay) {
  const _delay = delay || 200
  let timer
  return function () {
    const th = this
    const args = arguments
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(function () {
      timer = null
      fn.apply(th, args)
    }, _delay)
  }
}

// 防抖简版
export function _debounce2(fn, delay, immediate) {
  let timer
  return function (...args) {
    const context = this
    // 非立即执行版
    if (timer) clearTimeout(timer)

    if (!immediate) {
      timer = setTimeout(() => {
        fn.apply(context, args)
      }, delay)
    } else {
      // 立即执行版
      const callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, delay)
      if (callNow) fn.apply(context, args)
    }
  }
}
// 节流
export function _throttle(fn, delay = 200, isImmediate = false) {
  let valid = true
  if (isImmediate) {
    return function () {
      const th = this
      const args = arguments
      if (!valid) {
        //休息时间 暂不接客
        return false
      }
      // 工作时间，执行函数并且在间隔期内把状态位设为无效
      fn.apply(th, args)
      valid = false
      setTimeout(() => {
        valid = true
      }, delay)
    }
  } else {
    return function () {
      const th = this
      const args = arguments
      if (!valid) {
        //休息时间 暂不接客
        return false
      }
      // 工作时间，执行函数并且在间隔期内把状态位设为无效
      valid = false
      setTimeout(() => {
        fn.apply(th, args)
        valid = true
      }, delay)
    }
  }
}
// 价格保留2位小数
export const formatPrice = (value = 0) => {
  return value ? ((parseFloat(value) * 100) / 100).toFixed(2) : 0
}

export const setNavigationBarTitle = (value = '') => {
  let title = value || '幂友服务'
  uni.setNavigationBarTitle({
    title: title
  })
}

/**
 * 获取价格小数部分
 * @param {*} val
 * @returns
 */
export function formatDecimalPrice(val) {
  const valStr = val ? String(val) : '0'
  const decimal = valStr.indexOf('.') > -1 ? valStr.split('.')[1] : ''
  return decimal ? `.${decimal}` : ''
}

/**
 * 获取价格整数部分
 * @param {*} val
 * @returns
 */
export function formatIntPrice(val) {
  const valStr = val ? Number(val).toFixed(2) : '0.00'
  return valStr.split('.')[0]
}

export function jumpToMini(appId, path, query, extraData) {
  uni.navigateToMiniProgram({
    appId,
    extraData,
    path: `${path}?${qs.stringify(query)}`,
    envVersion: 'develop'
  })
}

export function genId(length) {
  if (!length || typeof length !== 'number') length = 20
  const data = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z'
  ]
  let nums = ''
  for (let i = 0; i < length; i++) {
    var r = parseInt(Math.random() * (data.length - 1))
    nums += data[r]
  }
  return nums
}

// 此方法用于未登录时跳转到登录页
export function relaunchToLoginPage(redirectPath, type = 'reLaunch') {
  if (type === 'reLaunch') {
    uni.reLaunch({
      url: `/login/index?targetUrl=${redirectPath}`
    })
  } else {
    uni.navigateTo({
      url: `/login/index?targetUrl=${redirectPath}`
    })
  }
}

// 利用这个特性，可以写出一个比typeof运算符更准确的类型判断函数
export const type = function (o) {
  const s = Object.prototype.toString.call(o)
  return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}

// 过滤数据中为null的值
export const replaceNull = (obj) => {
  for (let key in obj) {
    switch (type(obj[key])) {
      case 'object':
        replaceNull(obj[key])
        break
      case 'array':
        for (let i = 0; i < obj[key].length; i++) {
          replaceNull(obj[key][i])
        }
        break
      default:
        if (obj[key] === null) obj[key] = ''
    }
  }
  return obj
}

// 枚举转义
export const formatEnum = (enumDict, val) => {
  return enumDict.find((item) => item.value === val)?.label || ''
}
export function hasCreateIM() {
  let state = store.state.im
  return state.hasInitNIM && state.hasInitNIMUtil && getApp().globalData.NIMInstance && getApp().globalData.NIMUtilInstance
}
// 跳转至IM
export function goToIM(data) {
  console.log(data, 'datadatadatadatadata')
  const navigateTo = (params) => {
    switch (data.jumpType) {
      case 'redirectTo':
        uni.redirectTo(params)
        break
      default:
        uni.navigateTo(params)
        break
    }
  }
  if (hasCreateIM()) {
    navigateTo({
      url: `/IM/ChatRoom?${qs.stringify(data)}`
    })
  } else {
    navigateTo({
      url: `/IM/WaitIMCreate?${qs.stringify(data)}`
    })
  }
}

export function JSONParse(str) {
  if (typeof str === 'string') {
    try {
      const obj = JSON.parse(str)
      if (typeof obj === 'object' && obj) {
        return obj
      } else {
        return false
      }
    } catch (e) {
      return false
    }
  }
}

export function isIOS() {
  return new Promise((resolve) => {
    uni.getSystemInfo({
      success: function (res) {
        const isIOS = res.system.indexOf('iOS') > -1
        resolve(isIOS)
      },
      fail: (err) => {
        resolve(false)
      }
    })
  })
}

export function handleLogin(cb) {
  if (!isLogin()) {
    uni.reLaunch({
      url: '/login/index'
    })
    return
  }
  if (cb && typeof cb === 'function') {
    cb()
  }
}

/**
 * 将原对象的与目标对象相同的键对应的值，复制进目标对象,仅支持第一级属性
 * @param target 目标对象
 * @param source 原对象
 */
export function copyValue(target, source) {
  if (typeof target !== 'object' || typeof source !== 'object') {
    return
  }
  const keys = Object.keys(target)
  keys.forEach((key) => {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key]
    }
  })
}

// 是否包含emoji表情
export function hasEmoji(substring) {
  if (!substring) return false
  return /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi.test(
    substring
  )
}

// 点赞数展示
export function likeNumFormat(num) {
  // 小于1万 直接展示
  if (num < 10000) return num
  // 99万及以下 保留1位小数 直接展示如：10.0万
  if (num <= 990000) {
    const wanNum = Math.floor((num / 10000) * 10) / 10
    return `${wanNum.toFixed(1)}万`
  }
  return '99万+'
}

export function myTypeOf(data) {
  const str = Object.prototype.toString.call(data)
  const reg = str.match(/\[object (.+)\]/)
  return reg[1]
}

// 将页面路径及参数复制到剪切板
export function copyPageUrl(url, options) {
  const path = `${url}?${qs.stringify(options)}`
  // uni.setClipboardData({
  //   data: path,
  //   success: function () {}
  // })
}

//跳转到微信客服
export function jumpWechatCustomerService(callback) {
  // #ifdef MP-WEIXIN
  try {
    wx.openCustomerServiceChat({
      extInfo: { url: 'https://work.weixin.qq.com/kfid/kfc3239df52afbecb44' },
      corpId: 'ww85a5f2295e9995d3',
      success(res) {
        callback && callback(res)
      }
    })
  } catch (error) {
    uni.showToast({
      icon: 'none',
      title: '请更新至微信最新版本'
    })
  }
  // #endif
}
export function patchReg(str) {
  const numberArray = str?.match(/(\d+[Xx]\d*[Xx]*)|(\d+)/g) ?? []
  const item = numberArray
    .filter((item) => {
      return item.length === 11 || item.length === 18
    })
    .find((item) => {
      if (item.length === 11) {
        return patchPhone(item)
      } else {
        return patchIDCard(item)
      }
    })
  return Boolean(item)
}

export function patchPhone(str = '') {
  const phoneReg = /^[1][3,4,5,6,7,8,9]\d{9}$/
  return str?.match(phoneReg)?.length ?? 0 > 0
}
export function patchIDCard(str = '') {
  const IDCardReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
  return str?.match(IDCardReg)?.length ?? 0 > 0
}

export function isUndefinedOrNull(val) {
  return val === null || val === undefined
}

export function proxyData(obj) {
  return new Proxy(obj, {
    get(target, attr) {
      const v = Reflect.get(target, attr)
      return isUndefinedOrNull(v) ? '' : v
    },
    set(target, attr, value) {
      Reflect.set(target, attr, value)
    }
  })
}

// 去除富文本中img标签的class属性，在editor编辑器中，会反复追加无用样式导致最终接口内容长度超限报错,使用该方法去除
export function delHtmlImgClassProp(html) {
  const newHtml = html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, function (match, src) {
    console.log('match：', match)
    console.log('src：', src)
    //返回每个匹配的字符串
    return match.replace(/class=\"([^\"]*)\"/gi, 'class="xa_img_class_editor"')
  })
  return newHtml
}

export default {
  uuid,
  getDate,
  isNotComplete,
  parseTime,
  platformVersions,
  isLogin,
  checkEmail,
  isTaxpayerNo,
  formatCartData,
  _debounce,
  handlerServiceDays,
  formatPrice,
  formatDecimalPrice,
  formatIntPrice,
  replaceNull,
  formatEnum,
  relaunchToLoginPage,
  jumpWechatCustomerService,
  _debounce2
}
